import {
  BadRequestException,
  Body,
  Controller,
  Delete,
  forwardRef,
  Get,
  Inject,
  Post,
  Put,
  Query,
} from '@nestjs/common'
import { ApiOperation, ApiTags } from '@nestjs/swagger'

import { ApiResult } from '~/common/decorators/api-result.decorator'
import { IdParam } from '~/common/decorators/id-param.decorator'
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator'
import { UpdaterPipe } from '~/common/pipes/updater.pipe'
import { definePermission, Perm } from '~/modules/auth/decorators/permission.decorator'
import { DeviceEntity } from '~/modules/health/device/device.entity'
import { SseService } from '~/modules/sse/sse.service'

import { DeviceDto, DeviceQueryDto, DeviceUpdateDto } from './device.dto'
import { DeviceInfo } from './device.model'
import { DeviceService } from './device.service'

export const permissions = definePermission('health:device', {
  LIST: 'list',
  CREATE: 'create',
  READ: 'read',
  UPDATE: 'update',
  DELETE: 'delete',
} as const)

@ApiTags('Health - 设备模块')
@ApiSecurityAuth()
@Controller('devices')
export class DeviceController {
  constructor(
    private deviceService: DeviceService,
    @Inject(forwardRef(() => SseService))
    private sseService: SseService,
  ) {}

  @Get()
  @ApiOperation({ summary: '获取设备列表' })
  @ApiResult({ type: [DeviceEntity], isPage: true })
  @Perm(permissions.LIST)
  async list(@Query() dto: DeviceQueryDto) {
    return this.deviceService.list(dto)
  }

  @Get(':id')
  @ApiOperation({ summary: '获取设备信息' })
  @ApiResult({ type: DeviceInfo })
  @Perm(permissions.READ)
  async info(@IdParam() id: number) {
    return this.deviceService.info(id)
  }

  @Post()
  @ApiOperation({ summary: '新增设备' })
  @Perm(permissions.CREATE)
  async create(@Body() dto: DeviceDto): Promise<void> {
    await this.deviceService.create(dto)
  }

  @Put(':id')
  @ApiOperation({ summary: '更新设备' })
  @Perm(permissions.UPDATE)
  async update(@IdParam() id: number, @Body(UpdaterPipe)dto: DeviceUpdateDto): Promise<void> {
    await this.deviceService.update({ id }, dto)
  }

  @Delete(':id')
  @ApiOperation({ summary: '删除设备' })
  @Perm(permissions.DELETE)
  async delete(@IdParam() id: number): Promise<void> {
    const device = await this.deviceService.info(id)
    if (device.userId > 0)
      throw new BadRequestException('该设备存在关联用户，无法删除')

    await this.deviceService.delete(id)
  }
}
